package com.hxd.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.hxd.base.BaseServiceImpl;
import com.hxd.common.constant.FileConstants;
import com.hxd.common.core.manager.AsyncManager;
import com.hxd.common.core.manager.factory.AsyncFactory;
import com.hxd.common.utils.DateUtils;
import com.hxd.common.utils.SpringUtils;
import com.hxd.entity.SysOss;
import com.hxd.mapper.SysOssMapper;
import com.hxd.service.SysConfigService;
import com.hxd.service.SysOssService;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * <p>
    * 附件表 服务实现类
    * </p>
 *
 * @author zhoujw
 * @since 2019-12-19
 * @version v1.0
 */
@Service
public class SysOssServiceImpl extends BaseServiceImpl<SysOssMapper, SysOss> implements SysOssService {
	
	private Map<String, AtomicInteger> map = new HashMap<String, AtomicInteger>();
	
	private static String basePath;
	
	static {
		basePath = SpringUtils.getBean(SysConfigService.class).getValue(FileConstants.LOCAL_UPLOAD_PATH);
		if(basePath == null)
			basePath = FileConstants.DEFAULT_LOCAL_PATH;
	}
	
	public boolean isImage(String fileName) {
		Pattern p = Pattern.compile("^(jpeg|jpg|png|gif|bmp|webp)([\\w-./?%&=]*)?$");
		Matcher m = p.matcher(fileName.substring(fileName.lastIndexOf(".") + 1));
		if (m.find()) {
			return true;
		}
		return false;
	}

	public boolean isVedio(String fileName) {
		Pattern p = Pattern.compile("^(avi|mov|asf|wmv|navi|3gp|mkv|flv|f4v|rmvb|mp4)([\\w-./?%&=]*)?$");
		Matcher m = p.matcher(fileName.substring(fileName.lastIndexOf(".") + 1));
		if (m.find()) {
			return true;
		}
		return false;
	}
	
	/**
	 * 缓存已上传的分片数量
	 */
	public synchronized void uploadCount(String guid) {
		AtomicInteger ai = map.get(guid);
		if(ObjectUtil.isNull(ai)) {
			map.put(guid, new AtomicInteger(1));
		}else {
			ai.incrementAndGet();
			map.put(guid, ai);
		}
	}

	@Override
	public void uploadFile(String guid, Integer chunk, Integer chunks, MultipartFile file) throws IOException {
		uploadCount(guid);
		// 临时目录用来存放所有分片文件
        String tempFileDir = basePath + guid;
        File parentFileDir = new File(tempFileDir);
        if (!parentFileDir.exists()) {
            parentFileDir.mkdirs();
        }
        // 分片处理时 前台会多次调用上传接口 每次都会上传文件的一部分到后台
        File tempPartFile = new File(parentFileDir, guid + "_" + chunk + ".part");
        FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);
        AtomicInteger ai = map.get(guid);
        // 缓存计算为总片数 合并文件
        if(ai != null && ai.intValue() == chunks) {
        	mergeFile(guid, file);
        }
	}

	/**
	 * 合并文件
	 */
	public void mergeFile(String guid, MultipartFile file) throws IOException {
		// 临时文件目录
		File tempFileDir = new File(basePath + guid);
		if(tempFileDir.isDirectory()) {
			// 生成年月日路径
			StringBuffer path = new StringBuffer();
			path.append(DateUtils.getYear()).append("/").append(DateUtils.getMonth()).append("/").append(DateUtils.getDay());
			
			SysOss sysOss = new SysOss();
			sysOss.setName(file.getOriginalFilename());
			// 后缀
			String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
			sysOss.setSuffix(suffix);
			// 路径 2020/1/1/xxx.jpg
			String fileName = IdUtil.simpleUUID() + suffix;
			sysOss.setPath(path.toString() + "/" + fileName);
			// 最终路径
			String finalPath = basePath + path.toString();
			File folder = new File(finalPath);
			if (!folder.exists()) {
				folder.mkdirs();
			}
			// 最终文件
			File finalFile = new File(finalPath, fileName);
			// 删除缓存
			map.remove(guid);
			// 合并文件
			AsyncManager.me().execute(AsyncFactory.mergeFile(guid, tempFileDir, finalFile, sysOss));
        }
	}
	
}
